using System;
using System.Web;
using System.Threading;

namespace ContinualFlame.Ajax
{	
	public class ClientConnection : IDisposable
	{
		HttpResponse _response;
		ManualResetEvent _done = new ManualResetEvent(false);
		
		public ClientConnection(HttpResponse response)
		{
			_response = response;
			
			//
			// emit preamble of streaming 'document'
			//
			
		    _response.Write("// <html><body><script>\r\n");
			
			// handle normal XHR case
            _response.Write("__e = function(param) { document.__LocusClientInstance.StreamingEventCallback(param); }\r\n");
			
			// handle nested browser AX for IE
            _response.Write("if (document.parentWindow) __e = function(param) { document.parentWindow.__LocusClientInstance.StreamingEventCallback(param); }\r\n");

            // write ~1k of no-ops to force safari and IE to begin incremental processing
            int nopCount = 0;
            string nopString = "// <div>padding to make IE and Safari happy...</div>\r\n";
			
            while (nopCount < 1024)
            {
                _response.Write(nopString);
                nopCount += nopString.Length;
            }
			
			_response.Flush();
		}
		
		// TODO: shouldn't sit on an ASP worker thread, there is an IAsyncResult
		// using mechanism for efficiently parking a long request. Not sure if
		// mono/fastcgi/lighttpd supports it.
		public void WaitForExit()
		{
			_done.WaitOne();
		}
		
		public void SendMessage(Message m)
		{
			// TODO: could serialize once for broadcast and cache the JSON string
			
			_response.Write("__e(");
			
			string json = Newtonsoft.Json.JsonConvert.SerializeObject(m);
			_response.Write(json);	
		
			_response.Write(");\r\n");
			_response.Flush();
		}
		
		public void Dispose()
		{
			// don't close the response, in case our caller still wanted it			
			_response = null;
			
			// allow WaitForExit to return
			_done.Set();
		}
	}
}
